home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP08.ZIP / CHAP08 / PATRON / TENANT.CPP < prev   
C/C++ Source or Header  |  1993-06-07  |  22KB  |  940 lines

  1. /*
  2.  * TENANT.CPP
  3.  * Modifications for Chapter 8: None
  4.  *
  5.  * Implementation of the CTentant class which holds information
  6.  * for a single object on a page.  It maintains position, references
  7.  * to data, and a storage.
  8.  *
  9.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  10.  *
  11.  * Kraig Brockschmidt, Software Design Engineer
  12.  * Microsoft Systems Developer Relations
  13.  *
  14.  * Internet  :  kraigb@microsoft.com
  15.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  16.  */
  17.  
  18.  
  19. #include "patron.h"
  20.  
  21.  
  22. /*
  23.  * CTenant::CTenant
  24.  * CTenant::~CTenant
  25.  *
  26.  * Constructor Parameters:
  27.  *  dwID            DWORD identifier for this page.
  28.  *  hWnd            HWND of the pages window.
  29.  *  pPG             LPCPages to the parent structure.
  30.  */
  31.  
  32. CTenant::CTenant(DWORD dwID, HWND hWnd, LPCPages pPG)
  33.     {
  34.     m_hWnd=hWnd;
  35.     m_dwID=dwID;
  36.  
  37.     m_fInitialized=0;
  38.     m_pIStorage=NULL;
  39.     m_cOpens=0;
  40.  
  41.     m_pObj=NULL;
  42.     m_pPG =pPG;
  43.     return;
  44.     }
  45.  
  46.  
  47. CTenant::~CTenant(void)
  48.     {
  49.    #ifdef DEBUG
  50.     char    szTemp[128];
  51.     if (0!=m_cOpens)
  52.         {
  53.         wsprintf(szTemp, "::~CTenant m_cOpens=%lu", m_cOpens);
  54.         MessageBox(m_hWnd, szTemp, "Assert", MB_OK);
  55.         }
  56.    #endif
  57.  
  58.     if (NULL!=m_pObj)
  59.         {
  60.         //We know we only hold one reference from UCreate or FLoad
  61.         m_pObj->Release();
  62.         m_pObj=NULL;
  63.         }
  64.  
  65.     return;
  66.     }
  67.  
  68.  
  69.  
  70. /*
  71.  * CTenant::GetID
  72.  *
  73.  * Return Value:
  74.  *  DWORD           dwID field in this tenant.  This function is only here
  75.  *                  to avoid hiding inline implementations in pages.h
  76.  */
  77.  
  78. DWORD CTenant::GetID(void)
  79.     {
  80.     return m_dwID;
  81.     }
  82.  
  83.  
  84.  
  85. /*
  86.  * CTenant::GetStorageName
  87.  *
  88.  * Parameters:
  89.  *  pszName         LPSTR to a buffer in which to store the storage name
  90.  *                  for this tenant.
  91.  *
  92.  * Return Value:
  93.  *  UINT            Number of characters stored.
  94.  */
  95.  
  96. UINT CTenant::GetStorageName(LPSTR pszName)
  97.     {
  98.     return wsprintf(pszName, "Tenant %lu", m_dwID);
  99.     }
  100.  
  101.  
  102.  
  103.  
  104.  
  105. /*
  106.  * CTenant::UCreate
  107.  *
  108.  * Purpose:
  109.  *  Creates a new tenant of the given CLSID, which can be either a
  110.  *  static bitmap or metafile now (Chapter 7) and which may eventually
  111.  *  be any OLE object.
  112.  *
  113.  * Parameters:
  114.  *  tType           TENANTTYPE to create, either a static metafile, bitmap,
  115.  *                  or some kind of OLE object (later chapters)
  116.  *                  This determined which OleCreate* call we use.
  117.  *  pvType          LPVOID providing the relevant pointer from which
  118.  *                  to create the tenant, depending on iType.
  119.  *  pFE             LPFORMATETC specifying the type of renderings to use.
  120.  *  pptl            LPPOINTL in which we can store offset coordinates.
  121.  *  pszl            LPSIZEL where this object should store its lometric extents.
  122.  *  pIStorage       LPSTORAGE of the page we live in.  We have to
  123.  *                  create another storage under this for the tenant.
  124.  *  ppo             LPPATRONOBJECT containing placement data.
  125.  *  dwData          DWORD containing extra data, sensitive to iType.
  126.  *
  127.  * Return Value:
  128.  *  UINT            A UCREATE_* value depending on what we actually do.
  129.  */
  130.  
  131. UINT CTenant::UCreate(TENANTTYPE tType, LPVOID pvType, LPFORMATETC pFE
  132.     , LPPOINTL pptl, LPSIZEL pszl, LPSTORAGE pIStorage
  133.     , LPPATRONOBJECT ppo, DWORD dwData)
  134.     {
  135.     HRESULT         hr;
  136.     LPUNKNOWN       pObj;
  137.     UINT            uRet=UCREATE_GRAPHICONLY;
  138.  
  139.     if (NULL==pvType || NULL==pIStorage)
  140.         return UCREATE_FAILED;
  141.  
  142.     //Fail if this is called for an already living tenant.
  143.     if (m_fInitialized)
  144.         return UCREATE_FAILED;
  145.  
  146.     m_fInitialized=TRUE;
  147.  
  148.     //Create a new storage for this tenant.
  149.     if (!FOpen(pIStorage))
  150.         return UCREATE_FAILED;
  151.  
  152.     /*
  153.      * Get the placement info if it's here.  We either have a non-NULL
  154.      * LPPATRONOBJECT in ppo or we have to use default placement and
  155.      * retrieve the size from the object itself.
  156.      */
  157.     pszl->cx=0;
  158.     pszl->cy=0;
  159.  
  160.     if (NULL!=ppo)
  161.         {
  162.         *pFE=ppo->fe;
  163.         *pptl=ppo->ptl;
  164.         *pszl=ppo->szl;     //Could be 0,0 in which case we ask object
  165.  
  166.         uRet=UCREATE_PLACEDOBJECT;
  167.         }
  168.  
  169.     hr=ResultFromScode(E_FAIL);
  170.  
  171.     //Now create an object based specifically for the type.
  172.     switch (tType)
  173.         {
  174.         case TENANTTYPE_NULL:
  175.             break;
  176.  
  177.         case TENANTTYPE_STATIC:
  178.             /*
  179.              * We could use OleCreateStaticFromData here which does
  180.              * pretty much what we're doing below.  However, it does
  181.              * not allow us to control whether we paste a bitmap or
  182.              * a metafile--it uses metafile first, bitmap second.  For
  183.              * this reason we'll use code developed in Chapter 6's
  184.              * FreeLoader to affect the paste.
  185.              */
  186.             hr=CreateStatic((LPDATAOBJECT)pvType, pFE, &pObj);
  187.             break;
  188.  
  189.         default:
  190.             break;
  191.         }
  192.  
  193.     //If creation didn't work, get rid for the element FOpen created.
  194.     if (FAILED(hr))
  195.         {
  196.         Destroy(pIStorage);
  197.         return UCREATE_FAILED;
  198.         }
  199.  
  200.     //Otherwise, store the object pointer and initialize the tenant
  201.     m_pObj=pObj;
  202.     m_fe=*pFE;
  203.     m_dwState=TENANTSTATE_DEFAULT;
  204.  
  205.     //If we also saw PatronObjects on the clipboard, we have size already.
  206.  
  207.     if (0==pszl->cx && 0==pszl->cy)
  208.         {
  209.         LPOLEOBJECT     pIOleObject;
  210.  
  211.         //Try to get the real size of the object, default to 2"*2"
  212.         SETSIZEL((*pszl), 2*LOMETRIC_PER_INCH, 2*LOMETRIC_PER_INCH);
  213.         hr=pObj->QueryInterface(IID_IOleObject, (LPVOID FAR *)&pIOleObject);
  214.  
  215.         if (SUCCEEDED(hr))
  216.             {
  217.             SIZEL   szl;
  218.  
  219.             pIOleObject->GetExtent(pFE->dwAspect, &szl);
  220.             pIOleObject->Release();
  221.  
  222.             //Convert HIMETRIC to our LOMETRIC mapping
  223.             SETSIZEL((*pszl), szl.cx/10, szl.cy/10);
  224.             }
  225.         }
  226.  
  227.     return uRet;
  228.     }
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235. /*
  236.  * CTenant::FLoad
  237.  *
  238.  * Purpose:
  239.  *  Recreates the object living in this tenant in place of calling
  240.  *  FCreate.  This is used in loading as opposed to new creation.
  241.  *
  242.  * Parameters:
  243.  *  pIStorage       LPSTORAGE of the page we live in.
  244.  *  pFE             LPFORMATETC specifying the type of renderings to use.
  245.  *  prcl            LPRECTL where this object is positioned.
  246.  *
  247.  * Return Value:
  248.  *  BOOL            TRUE if successful, FALSE otherwise.
  249.  */
  250.  
  251. BOOL CTenant::FLoad(LPSTORAGE pIStorage, LPFORMATETC pFE, LPRECTL prcl)
  252.     {
  253.     HRESULT         hr;
  254.     LPUNKNOWN       pObj;
  255.  
  256.     if (NULL==pIStorage || NULL==pFE || NULL==prcl)
  257.         return FALSE;
  258.  
  259.     //Fail if this is called for an already living tenant.
  260.     if (m_fInitialized)
  261.         return FALSE;
  262.  
  263.     m_fInitialized=TRUE;
  264.  
  265.     //Open the storage for this tenant.
  266.     if (!FOpen(pIStorage))
  267.         return FALSE;
  268.  
  269.     hr=OleLoad(m_pIStorage, IID_IUnknown, NULL, (LPVOID FAR *)&pObj);
  270.  
  271.     if (FAILED(hr))
  272.         {
  273.         Destroy(pIStorage);
  274.         return FALSE;
  275.         }
  276.  
  277.     //Otherwise, store the object pointer and initialize the tenant
  278.     m_pObj=pObj;
  279.     m_fe=*pFE;
  280.     m_dwState=TENANTSTATE_DEFAULT;
  281.  
  282.     RectSet(prcl, FALSE);
  283.     return TRUE;
  284.     }
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293. /*
  294.  * CTenant::FOpen
  295.  *
  296.  * Purpose:
  297.  *  Retrieves the IStorage associated with this tenant.  The IStorage is
  298.  *  owned by the tenant and thus the tenant always holds a reference count.
  299.  *
  300.  *  If the storage is already open for this tenant, then this function will
  301.  *  AddRef it; therefore the caller must always match an FOpen with a Close.
  302.  *
  303.  * Parameters:
  304.  *  pIStorage       LPSTORAGE above this tenant (which has its own storage).
  305.  *
  306.  * Return Value:
  307.  *  BOOL            TRUE if opening succeeds, FALSE otherwise.
  308.  */
  309.  
  310. BOOL CTenant::FOpen(LPSTORAGE pIStorage)
  311.     {
  312.     HRESULT     hr=NOERROR;
  313.     DWORD       dwMode=STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
  314.     char        szTemp[32];
  315.  
  316.     if (NULL==m_pIStorage)
  317.         {
  318.         if (NULL==pIStorage